"""此文件根据执行表格获取各测试套件的路径及所属子系统"""
import sys

import pandas as pd
import os
import re
import json
from concurrent.futures import ThreadPoolExecutor

REPORT_PATH = "./"
SHEET_NAME = "RK3568_report"
XTS_PATH = "./"
WRITE_JSON = "hapinfo.json"

class TaskError(Exception):
    pass

# 将绝对路径转换为相对于基准路径的相对路径
def absolute_to_relative(absolute_path, base_path):

    absolute_path = os.path.abspath(absolute_path)
    base_path = os.path.abspath(base_path)
    common_prefix = os.path.commonprefix([absolute_path, base_path])
    relative_to_common = os.path.relpath(base_path, common_prefix)

    remaining_path = os.path.relpath(absolute_path, common_prefix)
    relative_path = os.path.join('..' * relative_to_common.count(os.sep), remaining_path)

    relative_path = os.path.normpath(relative_path)

    return relative_path

def read_excel(file_path, sheet_name):
    df = pd.read_excel(file_path, sheet_name=sheet_name)

    # 以 "Module" 列为键，其他列信息为值生成 map
    module_map = {}
    for index, row in df.iterrows():
        hap_name = row['Module']
        subsystem_name_en = row["英文子系统"]
        subsystem_name_zh = row["中文子系统"]
        duty = row["责任人"]
        hap_info = {}
        hap_info["subsystem_name_en"] = subsystem_name_en
        hap_info["subsystem_name_zh"] = subsystem_name_zh
        hap_info["duty"] = duty
        module_map[hap_name] = hap_info

    return module_map

# 处理单个 BUILD.gn 文件，返回匹配结果。
def process_build_gn(build_gn_path, match_set, regex_template, subsystem_regex):
    matches = {}
    try:
        # 读取文件内容
        with open(build_gn_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # 检查匹配项
        for item in match_set:
            regex = re.compile(regex_template.format(re.escape(item)))
            if regex.search(content):
                if item not in matches:
                    matches[item] = {"paths": [], "subsystem_names": []}
                matches[item]["paths"].append(build_gn_path)
                # 提取 subsystem_name
                subsystem_match = re.search(subsystem_regex, content)
                if subsystem_match:
                    subsystem_name = subsystem_match.group(1)
                    for item in matches.keys():
                        matches[item]["subsystem_names"].append(subsystem_name)
    except Exception as e:
        raise TaskError(f"Error processing {build_gn_path}: {e}")
    return matches

# 使用多线程查找匹配的 BUILD.gn 文件
def find_build_gn_files(result_map, root_path = XTS_PATH, max_threads=60):
    match_set = set(result_map.keys())
    # 匹配 hapname 的正则
    regex_template = r'(?<!:)(["\']?)\b{}\b\1'
    # 匹配 subsystem_name 的正则
    subsystem_regex = r'subsystem_name\s*=\s*["\']?([\w.-]+)["\']?'

    # 收集所有 BUILD.gn 文件路径
    build_gn_files = []
    for dirpath, _, filenames in os.walk(root_path):
        for filename in filenames:
            if filename == "BUILD.gn":
                build_gn_files.append(os.path.join(dirpath, filename))

    # 打印进度
    total_files = len(build_gn_files)
    completed_files = 0

    with ThreadPoolExecutor(max_threads) as executor:
        futures = [
            executor.submit(process_build_gn, path, match_set, regex_template, subsystem_regex)
            for path in build_gn_files
        ]
        print("after futures")
        try:
            for future in futures:
                matches = future.result()
                for key, data in matches.items():
                    if len(data["paths"]) == 0:
                        print(f"{key} does not match")
                    elif len(data["paths"]) == 1:
                        relative_path = absolute_to_relative(data["paths"][0], XTS_PATH)
                        result_map[key]["path"] = relative_path
                    else:
                        print(f"{key} matches more then one")
                        relative_paths = []
                        for path in data["paths"]:
                            relative_paths.append(absolute_to_relative(path, XTS_PATH));
                        result_map[key]["path"] = relative_paths
                    # 代码中获取的subsystem_name处理
                    if len(data["subsystem_names"]) == 0:
                        print(f"{key} does not match subsystem_name")
                    elif len(data["subsystem_names"]) == 1:
                        result_map[key]["subsystem_name_in_build"] = data["subsystem_names"][0]
                    else:
                        print(f"{key} matches more then one subsystem_name")
                        result_map[key]["subsystem_name_in_build"] = data["subsystem_names"]
                print(f"Progress:{completed_files}/{total_files}")
        except Exception as e:
            print(f"Task_failed: {e}")
            sys.exit(1)
def write_json(jsonInfo,jsonPath = WRITE_JSON):
    with open(jsonPath, 'w', encoding='utf-8') as json_file:
        # 使用json.dump()方法将字典转换为JSON格式并写入文件
        json.dump(jsonInfo, json_file, ensure_ascii=False, indent=4)

def run():
    # 读取excel形成map
    print("start")
    result_map = read_excel(REPORT_PATH, SHEET_NAME)
    print("read_excel finished")
    find_build_gn_files(result_map)
    print("find_build_gn_files finished")
    write_json(result_map)
    print("write_json finished")

if __name__ == '__main__':
    run()